#ifndef __DemoServer_h__
#define __DemoServer_h__

#include "stdafx.h"

#define WIN32_LEAN_AND_MEAN
#include "windows.h"

#include <iostream>
#include <conio.h>
#include <algorithm>

#include "ATMOS.h"
#include "ATMOS_LogManager.h"
#include "ATMOS_MSClient.h"
#include "ATMOS_MasterServerPacketID.h"

class DemoServer
{
	typedef std::list<std::string> GUIDList;

	class GameServerListener : public ATMOS::PacketListener
	{
		friend class DemoServer;

	public:
		GameServerListener( DemoServer *demoClient  );
		virtual ~GameServerListener();

		virtual void onAtmosPacket( ATMOS::Packet *packet );
		virtual void onDisconnectionNotification( const std::string &senderGUID );
		virtual void onAlreadyConnected( const std::string &senderGUID );
		virtual void onIncompatibleProtocolVersion( const std::string &senderGUID );
		virtual void onRemoteDisconnectionNotification( const std::string &senderGUID );
		virtual void onRemoteConnectionLost( const std::string &senderGUID );
		virtual void onNewIncomingConnection( const std::string &senderGUID );
		virtual void onConnectionBanned( const std::string &senderGUID );
		virtual void onConnectionAttemptFailed( const std::string &senderGUID );
		virtual void onNoFreeIncomingConnections( const std::string &senderGUID );
		virtual void onInvalidPassword( const std::string &senderGUID );
		virtual void onConnectionLost( const std::string &senderGUID );
		virtual void onConnectionRequestAccepted( const std::string &senderGUID );
		virtual void onUnknownPacket( const std::string &senderGUID );
	
	private:
		DemoServer *mDemoServer;
	};
	
	class MSClientListener : public ATMOS::PacketListener
	{
		friend class DemoServer;		

	public:
		MSClientListener( DemoServer *demoClient, const std::string &name );
		virtual ~MSClientListener();

		virtual void onAtmosPacket( ATMOS::Packet *packet );
		virtual void onDisconnectionNotification( const std::string &senderGUID );
		virtual void onAlreadyConnected( const std::string &senderGUID );
		virtual void onIncompatibleProtocolVersion( const std::string &senderGUID );
		virtual void onRemoteDisconnectionNotification( const std::string &senderGUID );
		virtual void onRemoteConnectionLost( const std::string &senderGUID );
		virtual void onNewIncomingConnection( const std::string &senderGUID );
		virtual void onConnectionBanned( const std::string &senderGUID );
		virtual void onConnectionAttemptFailed( const std::string &senderGUID );
		virtual void onNoFreeIncomingConnections( const std::string &senderGUID );
		virtual void onInvalidPassword( const std::string &senderGUID );
		virtual void onConnectionLost( const std::string &senderGUID );
		virtual void onConnectionRequestAccepted( const std::string &senderGUID );
		virtual void onUnknownPacket( const std::string &senderGUID );
	
	private:
		DemoServer *mDemoServer;
		std::string mName;
	};

public:
	DemoServer( const std::string &name, 
		const ATMOS::NetworkConnectionInfo &masterServerInfo,
		const ATMOS::NetworkConnectionInfo &serverInfo );
	virtual ~DemoServer();
	
	void update();

	void listClients();
	
	std::string getGameLocalGUID() const;
	std::string getMSLocalGUID() const;
	std::string getMSServerGUID() const;

private:
	void initializeConnectionToMasterServer( const std::string &name, 
		const ATMOS::NetworkConnectionInfo &masterServerInfo, int localGamePort );
	void shutdownConnectionToMasterServer();

	void initializeGameServerConnection( const ATMOS::NetworkConnectionInfo &serverInfo );
	void shutdownGameServerConnection();

private:
	ATMOS::LogManager *mLogManager;
	ATMOS::MSClient *mMSClient;
	ATMOS::NetworkManagerServer mServer;
	bool mServerInitialized;
	GUIDList mClients;
	std::string mMSServerGUID;

	GameServerListener *mGameServerListener;
	MSClientListener *mMSClientListener;
};

#endif